/**
 * 上分片上传统一入口
 * @author som<hd@vmeshou.com>
 * @date 2020-04-26
 */
import {
  toMd5
} from "./spark-md5";
import axios from "axios";
import store from "@/store";
/**
 * 执行上传的Requst
 */
const request = axios.create({
  baseURL: process.env.VUE_APP_BASE_UPLOAD_FILE + "/uploads",
  timeout: 15000, // request timeout
  withCredentials: false, // 不允许携带cookie
  transformRequest: []
});

// 请求之前的处理
request.interceptors.request.use(
  config => {
    // if (config.params) {
    //   config.params.upload_key = "fastVC";
    // } else {
    //   config.params = {
    //     upload_key: "fastVC"
    //   };
    // }
    if (config.method == "post") {
      // 上传文件
      config.headers["Content-Type"] = "multipart/form-data";
    } else {
      config.headers["Content-Type"] = "application/json; charset=UTF-8";
    }
    // 不允许请求缓存
    config.headers["Cache-Control"] = "no-cache";
    config.headers["clientId"] = "10000";
    config.headers["app-id"] = "10000";
    config.headers["app-key"] = "gPV3jpude7yhGycxAt3h2pcgh0DRL8Y9";

    return config;
  },
  error => {
    // Do something with request error
    console.log(error); // for debug
    Promise.reject(error);
  }
);

// 请求之后的处理
request.interceptors.response.use(
  /**
   * 下面的注释为通过在response里，自定义code来标示请求状态
   * 当code返回如下情况则说明权限有问题，登出并返回到登录页
   * 如想通过 xmlhttprequest 来状态码标识 逻辑可写在下面error中
   * 以下代码均为样例，请结合自生需求加以修改，若不需要，则可删除
   */
  response => {
    const res = response.data;
    return res;
  },
  error => {
    console.log(
      "-----------出现错误，状态码：" + error.response.status + "------------"
    );
    let errorInfo = "出现错误，请重试或检查";
    // console.log(error.response.headers)
    // 构造统一的返回体
    return Promise.reject(errorInfo + "：" + JSON.stringify(error.response));
  }
);
//===========================================================================
// 定义分片大小
var chunkSize = 10 * 1024 * 1024;
// 定义上传渠道
var channel = "10000";
// 定义文件分类
var category = "用户>头像";

function getResultData(result) {
  let data=result.data
  if (data) {
    // 拼接source
    result.source =
      `${process.env.VUE_APP_BASE_FILE}/${data.md5}/v.${data.ext}`;
    if (data.wh) {
      let sizes = data.wh.split('x');
      result.sourcewh =
        `${process.env.VUE_APP_BASE_FILE}/${data.md5}/w/${sizes[0]}/h/${sizes[1]}/d/true.${data.ext}`;
    }

  }
  return result;
}
/**
 * 上传入口
 */
export function upFile(file, fileType) {
  let ext = getFileExt(file.type);
  if (!ext) {
    return Promise.reject({
      error: "不允许上传的文件类型"
    });
  }
  file.ext = ext;
  //console.log(file);
  console.log(ext);
  if (fileType == "image") {
    if ("gif|jpg|jpeg|png".indexOf(ext) < 0) {
      return Promise.reject({
        error: "只能上传图片"
      });
    }
  } else if (fileType == "video") {
    if (
      "rmvb|flv|vob|mp4|m4v|mov|3gp|wmv|mp3|mkv|mpg|ts|avi|mpeg|avi|rm|wav|asf|divx|mpg|mpe|vod".indexOf(
        ext
      ) < 0
    ) {
      return Promise.reject({
        error: "只能上传视频"
      });
    }
  } else if (fileType == "file") {
    if ("pdf|doc|docx|ppt|pptx|rar|zip".indexOf(ext) < 0) {
      return Promise.reject({
        error: "只能上传文档或压缩包"
      });
    }
  } else {
    if (
      "pdf|doc|docx|ppt|pptx|rar|zip|rmvb|flv|vob|mp4|m4v|mov|3gp|wmv|mp3|mkv|mpg|ts|avi|mpeg|avi|rm|wav|asf|divx|mpg|mpe|vod|gif|jpg|jpeg|png"
      .indexOf(
        ext
      ) < 0
    ) {
      return Promise.reject({
        error: "不允许上传的文件类型"
      });
    }
  }
  if (file.category) {
    category = file.category;
  }
  // md5计算截取长度-前40M
  let md5Blob = 40 * 1024 * 1024;
  // 获取文件大小
  let fileSize = file.size;
  if (fileSize < md5Blob) {
    md5Blob = fileSize;
  }
  // 总片数
  let chunkCount = 1;
  // 初始化成功上传的片数
  let upSuccessChunk = 0;
  if (fileSize > chunkSize) {
    // 多个片
    chunkCount = Math.ceil(fileSize / chunkSize);
  }
  // 计算md5
  let fileReader = new FileReader();
  fileReader.readAsBinaryString(file.slice(0, md5Blob));
  //提取成功
  return new Promise((resolve, reject) => {
    fileReader.onload = function(evt) {
      if (evt.target.readyState == FileReader.DONE) {
        //二进制数据结果
        let binaryData = evt.target.result;
        //进行md5加密
        let md5 = toMd5(binaryData);
        console.log(file.name + "-得到的文件md5：" + md5);
        if (!md5) {
          return reject({
            error: "md5计算错误"
          });
        }
        // 上传之前的md5校验
        request({
            method: "get",
            params: {
              status: "md5Check",
              md5: md5,
              name: file.name,
              ext: ext
            }
          })
          .then(result => {
            if (result.ifExist) {
              // 秒传成功
              if (result.error) {
                console.log(result.error);
              }
              // 拼接source
              return resolve(getResultData(result));
            }
            // ----执行分片上传------
            return toUpload(0, md5);
          })
          .catch(response => {
            console.log(response);
            return reject({
              md5: md5,
              error: response
            });
          });
      }
    };
    // -----执行单片上传---------------
    function toUpload(currIndex, md5) {
      // 当前片大小
      let size = chunkSize;
      let start = currIndex * chunkSize;
      let end = start + (fileSize - currIndex * chunkSize);
      if (chunkCount > 1) {
        if (currIndex + 1 == chunkCount) {
          // 最后一片
          end = fileSize;
          // 最后一片的大小
          size = fileSize - start;
        } else {
          end = start + chunkSize;
        }
      }

      // 当前片是否上传的校验
      request({
          method: "get",
          params: {
            status: "chunkCheck",
            name: md5,
            chunkIndex: currIndex,
            size: size
          }
        })
        .then(data => {
          if (data.ifExist) {
            // 片秒传成功
            upSuccessChunk++;
            if (upSuccessChunk == chunkCount) {
              // 所有片都上传完毕，执行合并
              return toMerge(md5);
            }
          }
          // ----执行分片上传------
          let blob = file.slice(start, end);
          let postData = new FormData();
          postData.append("userId", store.getters.userId);
          postData.append("md5", md5);
          postData.append("uniqueFileName", md5);
          postData.append("chunkSize", chunkSize);
          postData.append("chunkIndex", currIndex);
          postData.append("file", blob);
          request({
              method: "post",
              data: postData
            })
            .then(data => {
              console.log(data);
              // ----上传成功-下一片------
              upSuccessChunk++;
              if (upSuccessChunk == chunkCount) {
                // 所有片都上传完毕，执行合并
                return toMerge(md5);
              } else {
                return toUpload(currIndex + 1, md5);
              }
            })
            .catch(response => {
              console.log(response);
              return reject({
                error: response
              });
            });
        })
        .catch(response => {
          console.log(response);
          return reject({
            error: response
          });
        });
    }
    // ------上传之后的合并--------------
    function toMerge(md5) {
      let params = {
        status: "chunksMerge",
        category: category,
        channel: channel,
        name: md5,
        chunks: chunkCount,
        ext: ext,
        filesize: file.size,
        fileoldname: file.name,
        md5: md5
      }
      request({
          method: "get",
          params: params
        })
        .then(result => {
          if (result.code === 10111) {

            return resolve(getResultData({data:params}));
          } else if (result.code) {
            return reject({
              error: result.code
            });
          }
          if (result.error) {
            return reject({
              error: result.error
            });
          }
          // 上传成功
          return resolve(getResultData(result));
        })
        .catch(response => {
          console.log(response);
          return reject({
            error: response
          });
        });
    }
  });
}
// 获取文件后缀
function getFileExt(type) {
  let ext = false;
  switch (type) {
    case "image/gif":
      ext = "gif";
      break;
    case "image/jpeg":
      ext = "jpg";
      break;
    case "image/png":
      ext = "png";
      break;
    case "application/vnd.ms-powerpoint":
      ext = "ppt";
      break;
    case "application/vnd.ms-excel":
      ext = "xls";
      break;
    case "application/vnd.openxmlformats-officedocument.presentationml.presentation":
      ext = "pptx";
      break;
    case "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet":
      ext = "xlsx";
      break;
    case "application/vnd.openxmlformats-officedocument.wordprocessingml.document":
      ext = "docx";
      break;
    case "application/msword":
      ext = "doc";
      break;
    case "application/pdf":
      ext = "pdf";
      break;
    case "application/x-rar-compressed":
      ext = "rar";
      break;
    case "application/zip":
      ext = "zip";
      break;
    case "audio/mpeg":
      ext = "mp3";
      break;
    case "audio/x-m4a":
      ext = "m4a";
      break;
    case "video/mp4":
      ext = "mp4";
      break;
    case "video/quicktime":
      ext = "mov";
      break;
    case "video/x-flv":
      ext = "flv";
      break;
    case "video/x-msvideo":
      ext = "avi";
      break;
    case "video/x-ms-wmv":
      ext = "vmv";
      break;
    default:
      ext = false;
  }
  return ext;
}
